#include <kernel/console.h>
#include <kernel/types.h>

volatile uint16_t* vga_buffer = (uint16_t*)0xB8000;

const int VGA_COLS = 80;
const int VGA_ROWS = 25;

int term_col = 0;
int term_row = 0;
uint8_t term_color = 0x0F; 
void term_init(void) {
    for (int y = 0; y < VGA_ROWS; y++) {
        for (int x = 0; x < VGA_COLS; x++) {
            const size_t index = y * VGA_COLS + x;
            vga_buffer[index] = (uint16_t)term_color << 8 | ' ';
        }
    }
}

void term_putchar(char c) {
    if (c == '\n') {
        term_col = 0;
        term_row++;
    } else {
        const size_t index = term_row * VGA_COLS + term_col;
        vga_buffer[index] = (uint16_t)term_color << 8 | c;
        term_col++;
    }

    if (term_col >= VGA_COLS) {
        term_col = 0;
        term_row++;
    }

    if (term_row >= VGA_ROWS) {
        for (int y = 1; y < VGA_ROWS; y++) {
            for (int x = 0; x < VGA_COLS; x++) {
                const size_t index_current = y * VGA_COLS + x;
                const size_t index_previous = (y - 1) * VGA_COLS + x;
                vga_buffer[index_previous] = vga_buffer[index_current];
            }
        }
        
        for (int x = 0; x < VGA_COLS; x++) {
            const size_t index = (VGA_ROWS - 1) * VGA_COLS + x;
            vga_buffer[index] = (uint16_t)term_color << 8 | ' ';
        }
        
        term_row = VGA_ROWS - 1;
    }
}

void term_write(const char* str) {
    for (size_t i = 0; str[i] != '\0'; i++) {
        term_putchar(str[i]);
    }
}
